{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 思路：\n",
    "- 获取数据:done\n",
    "- 获取样本X,标签y；将X，y的顺序随机打乱：done\n",
    "- 获取训练集60000；测试集10000：done\n",
    "- 获取一个样本数据：39000：2，之后测试用：done\n",
    "- 数据处理：目前MNIST数据集基本都是被处理好的数据集可以直接使用：done;补充：把y_train;y_test转换成int32类型\n",
    "- 引入K-近邻，做fit:K_近邻默认weights：uniform；n_neighbor=5:可以选择：distance和其他的neighbor数组合\n",
    "- GridSearchCV找到最好的参数{'weights':[],'n_neighbors':[]}\n",
    "- precision，recall评估\n",
    "- 要求是精度大于90%"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\program files (x86)\\microsoft visual studio\\shared\\python3.7.4\\lib\\site-packages\\sklearn\\feature_extraction\\text.py:17: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working\n",
      "  from collections import Mapping, defaultdict\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_mldata\n",
    "\n",
    "# 导入数据\n",
    "mnist = fetch_mldata('mnist-original', data_home='./')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "X=mnist['data']\n",
    "y=mnist['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 拆分数据集\n",
    "X_train,X_test,y_train,y_test=X[:60000,:],X[60000:,:],y[:60000],y[60000:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import sklearn\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 洗牌，重新划分\n",
    "shuffle_index=np.random.permutation(60000)\n",
    "X_train,y_train=X_train[shuffle_index],y[shuffle_index]\n",
    "shuffle_index=np.random.permutation(10000)\n",
    "X_test,y_test=X_test[shuffle_index],y_test[shuffle_index]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 随意确定一个值\n",
    "some_digit=X_train[39000]\n",
    "some_digit_img=some_digit.reshape(28,28)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "plt.imshow(some_digit_img,cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train=y_train.astype('int32')\n",
    "y_test=y_test.astype('int32')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 选出为1的\n",
    "y_train_1=(y_train==1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 距离计算 kn模型\n",
    "kn_clf=KNeighborsClassifier()\n",
    "kn_clf.fit(X_train,y_train_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 选定值进行测试\n",
    "some_digit=X_train[39000]\n",
    "some_digit=[some_digit]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 测试模型\n",
    "kn_clf.predict(some_digit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.metrics import precision_score\n",
    "from sklearn.metrics import recall_score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 错误\n",
    "- cross_val_score\n",
    "- cross_val_predict\n",
    "\n",
    "- 当区分错误的时候，容易出现错误：Found input variables with inconsistent numbers of samples: [60000, 3]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 交叉验证\n",
    "y_train_pred=cross_val_score(kn_clf,X_train,y_train_1,cv=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_score=y_train_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "y_train_1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 交叉验证 得分\n",
    "y_train_pred[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import cross_val_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_pred=cross_val_predict(kn_clf,X_train,y_train_1,cv=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 精度，召回\n",
    "precision=precision_score(y_train_1,y_train_pred)\n",
    "recall=recall_score(y_train_1,y_train_pred)\n",
    "print('precision:{:.2f}%'.format(precision*100))\n",
    "print('recall:{:.2f}%'.format(recall*100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 网格搜索，调参https://blog.csdn.net/Kyrie_Irving/article/details/90023615\n",
    "param_grid=[\n",
    "    {'weights':['uniform'],'n_neighbors':[i for i in range(1,11)]},\n",
    "    {'weights':['distance'],'n_neighbors':[i for i in range(1,11)]},\n",
    "]\n",
    "final_kn_clf=GridSearchCV(kn_clf,param_grid,cv=3,\n",
    "                         scoring='accuracy')\n",
    "final_kn_clf.fit(X_train,y_train_1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 验证\n",
    "final_kn_clf.predict(some_digit)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 最佳参数\n",
    "final_kn_clf.best_estimator_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 赋值\n",
    "kn_clf_new=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
    "                     metric_params=None, n_jobs=None, n_neighbors=1, p=2,\n",
    "                     weights='uniform')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 交叉验证\n",
    "y_train_pred=cross_val_predict(kn_clf_new,X_train,y_train_1,cv=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 精度，召回 \n",
    "precision=precision_score(y_train_1,y_train_pred)\n",
    "recall=recall_score(y_train_1,y_train_pred)\n",
    "print('precision:{:.2f}%'.format(precision*100))\n",
    "print('recall:{:.2f}%'.format(recall*100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test=y_test.astype('int32')\n",
    "y_test_1=(y_test==1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试集  进行验证\n",
    "y_test_pred=cross_val_predict(kn_clf_new,X_test,y_test_1,cv=2)\n",
    "precision=precision_score(y_test_1,y_test_pred)\n",
    "recall=recall_score(y_test_1,y_test_pred)\n",
    "print('precision:{:.2f}%'.format(precision*100))\n",
    "print('recall:{:.2f}%'.format(recall*100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Conclusion\n",
    "- KNeighborsClassfier\n",
    "    - precision：0.9878112484764061\n",
    "    - recall：0.9521651560926485\n",
    "    \n",
    "- GridSearchCV:best_estimator:\n",
    "    - precision:98.23%\n",
    "    - recall:96.04%\n",
    "- test_score\n",
    "    - precision:97.59%\n",
    "    - recall:93.99%"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
